class WebSerialPlugin {
    static  keepReading=false;
    static port=null;
    static readTimeOut=0;
    static recBuffer=[];
    static recFlag=0;
    static config= {
        baudRate: 112500,
        dataBits: 8,
        stopBits: 1,
        parity: 'none',
        flowControl: 'none'
    }


    static connectEvent=(e)=>{
        console.log("connect",e);
    }
    static disconnectEvent=(e)=>{
        console.log("disconnect",e);
    }

    static messageEvent=(d)=>{
        console.log(d);
    }

    static async selectPort(){
        // 浏览器支持serial
        if ('serial' in navigator) {
            // 获取用户之前授予该网站访问权限的所有串口
            const ports = await navigator.serial.getPorts();
            if (WebSerialPlugin.port === null || WebSerialPlugin.port ==undefined) {
                if (ports.length > 0) {
                    // 已经连接过
                    WebSerialPlugin.port = ports[0]
                    await WebSerialPlugin.open()
                    return
                }
                // 提示用户选择一个串口
                WebSerialPlugin.port = await navigator.serial.requestPort()
                WebSerialPlugin.keepReading=false;
                await WebSerialPlugin.open()
            }
        } else {
            alert('你的浏览器不支持串口连接')
        }

    }


    static async open() {
        try {
            await WebSerialPlugin.port.open(WebSerialPlugin.config);
            console.log('串口打开成功', WebSerialPlugin.port)
            WebSerialPlugin.port.onconnect=(event) => {
                WebSerialPlugin.connectEvent(event);
            };
            WebSerialPlugin.port.ondisconnect= (event) => {
                WebSerialPlugin.disconnectEvent(event);
            };
            WebSerialPlugin.reader = WebSerialPlugin.port.readable.getReader()
            WebSerialPlugin.writer = WebSerialPlugin.port.writable.getWriter()
            WebSerialPlugin.keepReading=true;
            while (WebSerialPlugin.port.readable &&   WebSerialPlugin.keepReading) {
                try {
                    while (true) {
                        const { value, done } = await  WebSerialPlugin.reader.read();
                        if (done) {
                            // Allow the serial port to be closed later.
                            WebSerialPlugin.reader.releaseLock();
                            // Allow the serial port to be closed later.
                            WebSerialPlugin.writer.releaseLock();
                            break;
                        }
                        if (value) {
                             let vArr= Array.from(value);
                             if(WebSerialPlugin.readTimeOut==0){
                                 WebSerialPlugin.messageEvent(vArr);
                                 WebSerialPlugin.recBuffer=[];
                                 continue;
                             }else {
                                 if(WebSerialPlugin.recBuffer.length==0){
                                     WebSerialPlugin.recFlag=1;
                                     WebSerialPlugin.recBuffer.push(...vArr);
                                     setTimeout(()=>{
                                         if(WebSerialPlugin.recFlag){
                                             WebSerialPlugin.messageEvent(WebSerialPlugin.recBuffer);
                                             WebSerialPlugin.recBuffer=[];
                                             WebSerialPlugin.recFlag=0;
                                         }
                                     },WebSerialPlugin.readTimeOut)
                                 }else {
                                     WebSerialPlugin.recFlag=0;
                                     WebSerialPlugin.recBuffer.push(...vArr);
                                     WebSerialPlugin.messageEvent(WebSerialPlugin.recBuffer);
                                     WebSerialPlugin.recBuffer=[];
                                 }
                             }

                        }
                    }
                } catch (error) {
                    // Handle non-fatal read error.
                    console.error("EEEEEEEEE",error);

                } finally {
                    console.log(WebSerialPlugin.port.readable, WebSerialPlugin.keepReading);
                }
            }
        }catch (e){
            console.error(e)
        }

    }

    static async forget() {
        let serPortList= await navigator.serial.getPorts();
        for (let i=0;i<serPortList.length;i++){
            let serPort=serPortList[i];
            try {
                serPort.close();
            }catch (e){

            }
            serPort.forget();
        }
        WebSerialPlugin.port=null;
        WebSerialPlugin.writer=null;
    }


    static async send(v) {
        if(WebSerialPlugin.port){
            WebSerialPlugin.keepReading=false;
            const data = new Uint8Array(v)
            await  WebSerialPlugin.writer.write(data)
            WebSerialPlugin.keepReading=true;
        }

    }


}